package modelos;

import java.io.FileNotFoundException;
import java.io.IOException;

import edu.bonn.cs.iv.bonnmotion.MobileNode;
import edu.bonn.cs.iv.bonnmotion.Position;
import edu.bonn.cs.iv.bonnmotion.RandomSpeedBase;
import edu.bonn.cs.iv.bonnmotion.Scenario;

public class ModeloSemLimites extends RandomSpeedBase {

	private static final String MODEL_NAME = "ModeloSemLimites";

	private double deltaAngMax = 180.0;
	
	public ModeloSemLimites(int nodes, double x, double y, double duration, double ignore, long randomSeed, double minspeed, double maxspeed, double maxpause) {
		super(nodes, x, y, duration, ignore, randomSeed, minspeed, maxspeed, maxpause);
		generate();
	}

	public ModeloSemLimites( String[] args ) {
		go(args);
	}

	public void go( String[] args ) {
		super.go(args);
		generate();
	}

	public void generate() {
		preGeneration();

		for (int i = 0; i < this.nodeCount(); i++) {
			node[i] = new MobileNode();

			double radianos = 0.0; 
			double deltaAng = 0.0;
			double speed = 0.0;
			Position pos = randomNextPosition();
			
			for (double t = 0.0; t < this.duration; t += 5) {
				speed = (maxspeed - minspeed) * randomNextDouble() + minspeed;
				deltaAng = ((2 * deltaAngMax) * randomNextDouble() - deltaAngMax) * 2 * Math.PI / 360;
				radianos += deltaAng;
								
				pos = getNextPosition(radianos, speed, pos, t);
				
				if (! (node[i].add(t, pos)))
					throw new RuntimeException(MODEL_NAME + ".go: error while adding waypoint");
			} 
		}

		postGeneration();
	}

	
	/**
	 * Calcula a proxima posicao.
	 * @param angAtual angulo em radianos
	 * @param velAtual velocidade
	 * @param pAnt     posicao anterior
	 * @return a nova posicao do MN
	 */
	private Position getNextPosition(double angAtual, double velAtual, Position pAnt, double tempo) {
		double x_ = 0.0, y_ = 0.0;

		x_ = pAnt.x + velAtual * Math.cos(angAtual) * tempo;
		y_ = pAnt.y + velAtual * Math.sin(angAtual) * tempo;
		
		// se sai dos limites, ele anda na borda
		x_ = (x_ <  0.0) ? (x + x_) : x_;
		x_ = (x_ >  x) ?  (x_ - x) : x_;
		
		y_ = (y_ <  0.0) ? (y + y_) : y_;
		y_ = (y_ >  y) ?  (y_ - y) : y_;
		
		return new Position(x_, y_);
	}

	public void write( String _name ) throws FileNotFoundException, IOException {
		String[] p = new String[1];
		p[0] = "deltaAngMax=" + deltaAngMax;
		super.write(_name, p);
	}

	protected boolean parseArg(String key, String val) {
		if (key.equals("deltaAngMax")) {
			deltaAngMax = Double.parseDouble(val);
		} else return super.parseArg(key, val);
		
		return true;
	}

	protected boolean parseArg(char key, String val) {
		switch (key) {
		case 'q':
			deltaAngMax = Double.parseDouble(val);
			return true;
		default:
			return super.parseArg(key, val);
		}
	}

	public static void printHelp() {
		Scenario.printHelp();
		System.out.println( MODEL_NAME + ":" );
		System.out.println("\t-q <angulo maximo de variacao no intervalo [0;180] graus>");
	}

}
